import qs from "qs";
import {Message, Loading} from "element-ui";
import axios from "axios";

axios.defaults.baseURL = process.env.VUE_APP_BASE_URL;
axios.defaults.timeout = 30000;

let loading = null;

const showLoading = (text) => {
    loading = Loading.service({
        lock: true,
        text: text ? text : '加载中……',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
    })
}

const hideLoading = () => {
    loading.close();
}


//showFullScreenLoading() 与 tryHideFullScreenLoading() 目的是合并同一页面多个请求触发loading

let needLoadingRequestCount = 0 //声明一个变量

let showFullScreenLoading = (text) => {
    if (needLoadingRequestCount === 0) { //当等于0时证明第一次请求 这时开启loading
        showLoading(text)
    }
    needLoadingRequestCount++ //全局变量值++
}

let tryHideFullScreenLoading = () => {
    if (needLoadingRequestCount <= 0) return //小于等于0 证明没有开启loading 此时return
    needLoadingRequestCount-- //正常响应后 全局变量 --
    if (needLoadingRequestCount === 0) {  //等于0 时证明全部加载完毕 此时结束loading 加载
        hideLoading()
    }
}

axios.interceptors.request.use(
    config => {
        let token = window.localStorage.getItem("token");
        if (token) {
            let tokenName = window.localStorage.getItem("tokenName");
            config.headers[tokenName] = token;
        }
        config.headers['Content-Type'] = 'application/json;charset=UTF-8'
        if (config.showLoading) {
            showFullScreenLoading(config.showLoadingText);
        }
        return config;
    },
    error => {
        return Promise.reject(error)
    }
)

axios.interceptors.response.use(
    response => {
        if (response.config && response.config.showLoading) {
            tryHideFullScreenLoading();
        }
        let data = response.data;
        if (data.code === 401) {
            Message.warning(data.message)
            window.localStorage.removeItem("token")
            window.localStorage.removeItem("tokenName")
            window.localStorage.removeItem("name")
            window.location.href='/login';
        }
        if (response.config && !response.config.hideMessage) {
            if (data.code === 200) {
                Message.success({
                    message: data.message,
                    duration: 1000
                });
            } else {
                Message.error(data.message);
            }
        }

        return data
    },
    error => {
        console.log('------请求错误------')
        console.log(error.response)
        Message.error("请求失败，服务器错误")
        return Promise.reject(error)
    }
)

//预处理配置
const pretreatConfig = (_config) => {
    if (_config && 'dataType' in _config) {
        if (_config.dataType === 'json') {
            Object.assign(_config, {
                headers: {
                    'Content-Type': 'application/json;charset=UTF-8'
                }
            });
        } else if (_config.dataType === 'formdata') {
            Object.assign(_config, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            });
        }
    }
    return _config;
};

/**
 * 打印api信息
 * @param {api地址} url
 * @param {api参数} data
 */
const printApiInfo = (url, data) => {
    if (process.env.NODE_ENV !== 'production') {
        console.log('\n\n');
        console.group('---------------开始发送API请求------------');
        console.log('API基础地址', process.env.VUE_APP_BASE_URL);
        console.log('API请求地址', url);
        const temp = Object.keys(data);
        if (temp.length) {
            console.group('API请求参数');
            temp.forEach((x) => {
                console.log(`${x} = ${data[x]}`);
            });
            console.groupEnd();
        }
        console.log('\n\n');
        console.groupEnd();
    }
};

const get = (url, data = {}, config) => {
    config = pretreatConfig(config);
    printApiInfo(url, data);
    return axios.get(url, {
        ...config,
        params: data,
        paramsSerializer: function (params) {
            return qs.stringify(params, {arrayFormat: 'indices'})
        }
    });
}

const post = (url, data = {}, config, json = true) => {
    config = pretreatConfig(config);
    printApiInfo(url, data);
    return axios.post(url, json ? JSON.stringify(data) : qs.stringify(data), {
        ...config
    });
}

const put = (url, data = {}, config, json = true) => {
    config = pretreatConfig(config);
    printApiInfo(url, data);
    return axios.put(url, json ? JSON.stringify(data) : qs.stringify(data), {
        ...config
    });
}

const del = (url, data = {}, config, json = true) => {
    config = pretreatConfig(config);
    printApiInfo(url, data);
    return axios.delete(url, {
        ...config,
        params: json ? JSON.stringify(data) : qs.stringify(data)
    });
}

const download = (url, data = {}, config) => {
    config = pretreatConfig(config);
    printApiInfo(url, data);
    return axios.get(url, {
        ...config,
        params: data,
        responseType: 'blob',
        paramsSerializer: function (params) {
            return qs.stringify(params, {arrayFormat: 'indices'})
        }
    }).then(res => {
        let blob = new Blob([res], {
            type: "application/vnd.ms-excel"
        });
        let objectUrl = URL.createObjectURL(blob);

        let a = document.createElement("a");
        a.href = objectUrl;
        a.download = "账单";
        //下面这个写法兼容火狐
        a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
        window.URL.revokeObjectURL(blob);
    });
}


const getTokenHeader = () => {
    let token = window.localStorage.getItem("token");
    if (token) {
        let tokenName = window.localStorage.getItem("tokenName");
        let header = {};
        header[tokenName] = token;
        return header
    }
    return {}
}

export default {
    get,
    post,
    put,
    del,
    download,
    getTokenHeader
}
